﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;

namespace theguineasyndrome
{
    public class FireWeapon : Weapon
    {
        private Texture2D[] dropTextures;
        private Texture2D[] flakeTextures;

        private SoundEffect primarySound;
        private int lastTimePrimaryPlayed;

        private SoundEffect cracklingSound;

        private List<FireDrop> drops;
        private Random random;

        private Clouds clouds;

        public FireWeapon(Texture2D[] flakeTextures, Texture2D[] dropTextures, SoundEffect primarySound, SoundEffect cracklingSound)
        {
            this.flakeTextures = flakeTextures;
            this.dropTextures = dropTextures;
            this.primarySound = primarySound;
            this.cracklingSound = cracklingSound;
            lastTimePrimaryPlayed = 0;
            drops = new List<FireDrop>();
            random = new Random();
        }

        public void setClouds(Clouds clouds)
        {
            this.clouds = clouds;
        }

        public override Vector2 firePrimary(int time, Vector2 position, Vector2 speed)
        {
            if (lastTimePrimaryPlayed < time - 300)
            {
                primarySound.Play();
                lastTimePrimaryPlayed = time;
            }

            speed *= 20;

            for (int i = 1; i <= 7; i++)
            {
                speed.X += ((float)random.NextDouble() - 0.5f) * 1.5f;
                speed.Y += ((float)random.NextDouble() - 0.5f) * 1.5f;

                drops.Add(new FireDrop(level, clouds, getRandomFlakeTexture(), cracklingSound, position, speed, FireDrop.LIFE_TIME, time, FireDrop.MAX_AGE));
            }

            return new Vector2();
        }

        public override Vector2 fireSecondary(int time, Vector2 position, Vector2 speed)
        {
            return new Vector2();
        }

        public override float getPrimaryPeriod()
        {
            return 15;
        }

        public override float getSecondaryPeriod()
        {
            return 0;
        }

        private Texture2D getRandomFlakeTexture()
        {
            return flakeTextures[random.Next(flakeTextures.Length)];
        }

        private Texture2D getRandomDropTexture()
        {
            return dropTextures[random.Next(dropTextures.Length)];
        }

        public override void Update(GameTime gameTime)
        {
            List<FireDrop> newDrops = new List<FireDrop>();

            int time = (int)gameTime.TotalGameTime.TotalMilliseconds;

            for (int i = drops.Count - 1; i >= 0; i--)
            {
                FireDrop drop = drops[i];
                drop.Update(gameTime);
                int dropAge = drop.getAge();
                int nextDropAge = FireDrop.MAX_AGE - dropAge;
                if (drop.shouldBeDead())
                {
                    drops.RemoveAt(i);
                }
                else if (drop.isDead() && nextDropAge > 100)
                {
                    ObstacleElement killingObstacle = drop.getKillingObstacle();

                    if (killingObstacle != null && killingObstacle is BurnableElement)
                    {
                        level.removeElement(killingObstacle);
                        cracklingSound.Play();

                        for (int j = 0; j < 10; j++)
                            clouds.add(killingObstacle.Center + new Vector2((float)(random.NextDouble() - 0.5) * killingObstacle.Width, (float)(random.NextDouble() - 0.5) * killingObstacle.Height));
                    }

                    float lifeTime = drop.getLifeTime() - 0.5f - (float)random.NextDouble() / 2;
                    if (lifeTime > 0)
                    {
                        Vector2 speed = drop.NextDropSpeed;

                        int numDrops = random.Next(0, 2);
                        for (int j = 0; j < numDrops; j++)
                        {
                            speed.X = speed.X + (float)(random.NextDouble() - 0.5) * lifeTime * 3;
                            speed.Y = speed.Y + (float)(random.NextDouble() - 0.5) * lifeTime * 3;
                            speed *= 0.2f;
                            newDrops.Add(new FireDrop(level, clouds, getRandomDropTexture(), cracklingSound, drop.Position, speed, FireDrop.LIFE_TIME, time, nextDropAge));
                        }
                    }
                    drops.RemoveAt(i);
                }
            }

            foreach (FireDrop newDrop in newDrops)
                drops.Add(newDrop);
        }

        public override void queueDrawing(Camera camera)
        {
            foreach (FireDrop drop in drops)
                drop.queueDrawing(camera);
        }

        public override bool primaryRequiresJustClicked()
        {
            return false;
        }

        public override bool secondaryRequiresJustClicked()
        {
            return false;
        }

        public override void clear()
        {
            drops.Clear();
        }
    }
}
